home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr47
/
ucrasm27.zip
/
SOURCE.ZIP
/
INSCURM.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-06-12
|
6KB
|
277 lines
; Need to include "lists.a" in order to get list structure definition.
include lists.a
extrn sl_malloc:far
wp equ <word ptr> ;I'm a lazy typist
; Special case to handle MASM 6.0 vs. all other assemblers:
; If not MASM 5.1 or MASM 6.0, set the version to 5.00:
ifndef @version
@version equ 500
endif
StdGrp group stdlib,stddata
stddata segment para public 'sldata'
stddata ends
stdlib segment para public 'slcode'
assume cs:stdgrp
; sl_InsertCurm- DX:SI points at a block of data bytes.
; ES:DI points at a list.
; This routine allocates storage for a new node on the
; heap, copies the data from DX:SI to the new node,
; and then links in the new node to the list before
; the current node.
;
; Returns the carry set if memory allocation error
; occurs.
;
; Randall Hyde 3/12/92
;
public sl_InsertCurm
sl_InsertCurm proc far
pushf
push ds
push ax
push bx
push cx
push es
push di
cld
if @version ge 600
; MASM 6.0 version goes here
; First, allocate storage for the new node:
mov cx, es:[di].List.ListSize
push cx ;Save for later
add cx, size NODE ;Add in overhead
call sl_malloc ;Go get the memory
pop cx ;Get real length back.
jc BadInsert ;If malloc error
push di ;Save ptr to new NODE.
; Compute offset to actual data area (skipping over list pointers, etc.)
add di, size Node
mov ds, dx
rep movsb ;Copy the node's data.
pop si ;Get ptr to original node
mov cx, es ;Make ds:si point at node.
mov ds, cx
pop di ;Get ptr to list var
pop es
push es
push di
; At this point, DS:SI points at the new node on the heap and ES:DI points
; at the list variable.
; See if the the list is empty:
cmp wp es:[di].List.Head+2, 0
jne ListHasNodes
; If this is an empty list (list is empty if HEAD is NIL), then build the
; list from this single node.
mov wp es:[di].List.Tail, si
mov wp es:[di].List.Head, si
mov wp es:[di].List.CurrentNode, si
mov wp es:[di].List.Tail+2, ds
mov wp es:[di].List.Head+2, ds
mov wp es:[di].List.CurrentNode+2, ds
; Set the link fields of this new node to NIL.
mov wp [si].Node.Next, 0
mov wp [si].Node.Prev, 0
mov wp [si].Node.Next+2, 0
mov wp [si].Node.Prev+2, 0
pop di
pop es
jmp GoodInsert
;If there were items in the list, perform the insert down here.
ListHasNodes: les di, es:[di].List.CurrentNode ;Get ptr to item
mov ax, wp es:[di].Node.Prev ;Get ptr to prev
mov bx, wp es:[di].Node.Prev+2 ; node and save.
; Use the address of CurrentNode as the next ptr for the new node.
mov wp ds:[si].Node.Next, di ;Patch in link
mov wp ds:[si].Node.Next+2, es
; Okay, store the new node's address into the PREV field of the current node
mov wp es:[di].Node.Prev, si ;Patch in fwd ptr
mov wp es:[di].Node.Prev+2, ds
; Set the PREV field of the new node to the original previous node.
mov wp ds:[si].Node.Prev, ax
mov wp ds:[si].Node.Prev+2, bx
; Set the Next field of the original previous node to point at the new
; node:
mov es, bx
mov di, ax
mov wp es:[di].Node.Next, si
mov wp es:[di].Node.Next+2, ds
; Set the CurrentNode ptr to the new node
pop di ;Retrive ptr to list var.
pop es
mov wp es:[di].List.CurrentNode, si
mov wp es:[di].List.CurrentNode+2, ds
else
; All other assemblers come down here:
; First, allocate storage for the new node:
mov cx, es:[di].ListSize
push cx ;Save for later
add cx, size NODE ;Add in overhead
call sl_malloc ;Go get the memory
pop cx ;Get real length back.
jnc GoodIns
jmp BadInsert ;If malloc error
GoodIns: push di ;Save ptr to new NODE.
; Compute offset to actual data area (skipping over list pointers, etc.)
add di, size Node
mov ds, dx
rep movsb ;Copy the node's data.
pop si ;Get ptr to original node
mov cx, es ;Make ds:si point at node.
mov ds, cx
pop di ;Get ptr to list var
pop es
push es
push di
; At this point, DS:SI points at the new node on the heap and ES:DI points
; at the list variable.
; See if the the list is empty:
cmp wp es:[di].Head+2, 0
jne ListHasNodes
; If this is an empty list (list is empty if HEAD is NIL), then build the
; list from this single node.
mov wp es:[di].Tail, si
mov wp es:[di].Head, si
mov wp es:[di].CurrentNode, si
mov wp es:[di].Tail+2, ds
mov wp es:[di].Head+2, ds
mov wp es:[di].CurrentNode+2, ds
; Set the link fields of this new node to NIL.
mov wp [si].Next, 0
mov wp [si].Prev, 0
mov wp [si].Next+2, 0
mov wp [si].Prev+2, 0
pop di
pop es
jmp GoodInsert
;If there were items in the list, perform the insert down here.
ListHasNodes: les di, es:[di].CurrentNode ;Get ptr to item
mov ax, word ptr es:[di].Prev ;Get ptr to prev
mov bx, word ptr es:[di].Prev+2 ; node and save.
; Use the address of CurrentNode as the next ptr for the new node.
mov wp ds:[si].Next, di ;Patch in link
mov wp ds:[si].Next+2, es
; Okay, store the new node's address into the PREV field of the current node
mov wp es:[di].Prev, si ;Patch in fwd ptr
mov wp es:[di].Prev+2, ds
; Set the PREV field of the new node to the original previous node.
mov wp ds:[si].Prev, ax
mov wp ds:[si].Prev+2, bx
; Set the Next field of the original previous node to point at the new
; node:
mov es, bx
mov di, ax
mov wp es:[di].Next, si
mov wp es:[di].Next+2, ds
; Set the CurrentNode ptr to the new node
pop di ;Retrive ptr to list var.
pop es
mov wp es:[di].CurrentNode, si
mov wp es:[di].CurrentNode+2, ds
endif
; DANGER WILL ROBINSON! Multiple exit points. Be wary of these if you
; change the way things are pushed on the stack.
GoodInsert: pop cx
pop bx
pop ax
pop ds
popf
clc
ret
BadInsert: pop di
pop es
pop cx
pop bx
pop ax
pop ds
popf
stc
ret
sl_InsertCurm endp
stdlib ends
end